package grisar.gris;

import grisar.gris.helpers.PhotoShop;
import grisar.gris.helpers.ResourceAllocator;
import grisar.gris.struct.Direction;
import grisar.gris.struct.MPoint;

import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Point;

public class MapParser {

	/*
	 * 0 = bakgrund
	 * 3 = mål för fiender
	 * 
	 * n = ner
	 * u = upp
	 * v = vänster
	 * h = höger
	 * x = kryss
	 * 
	 * N = start ner
	 * U = start upp
	 * V = start vänster
	 * H = start höger
	 * 
	 */
	List<LinkedList<MPoint>> startMPoints = new LinkedList<LinkedList<MPoint>>();

	LinkedList<LinkedList<MPoint>> paths = new LinkedList<LinkedList<MPoint>>();

	String map1 ="00hhhhhhn0000\n" + 
			"00u00000n0000\n" + 
			"Hhu00000hhhn0\n" + 
			"00000000000n0\n" + 
			"3vv00000nvvv0\n" + 
			"00u00000n0000\n" + 
			"00uvvvvvv0000\n" +
			"0000000000000\n"; 

	// [rader/y] [kolumner/x]
	char[][] map = new char[8][13]; //:) xD
	Map<Point, Bitmap> roadBitmaps = new HashMap<Point, Bitmap>();
	
	public MapParser(int level) {
		parsetest2();
		
		generateRoad();
	}
	public void parsetest2() {
		String[] rader = map1.split("\n");
		for (int y = 0; y < rader.length; y++) {
			for (int x = 0; x < rader[y].length(); x++) {
				map[y][x] = rader[y].charAt(x);
				if (map[y][x] == 'U') {
					paths.add(new LinkedList<MPoint>());
					paths.get(paths.size()-1).add(new MPoint(new Point(x,y), Direction.up));
				}
				else if (map[y][x] == 'H') {
					paths.add(new LinkedList<MPoint>());
					paths.get(paths.size()-1).add(new MPoint(new Point(x,y), Direction.right));
				}
				else if (map[y][x] == 'N') {
					paths.add(new LinkedList<MPoint>());
					paths.get(paths.size()-1).add(new MPoint(new Point(x,y), Direction.down));
				}
				else if (map[y][x] == 'V') {
					paths.add(new LinkedList<MPoint>());
					paths.get(paths.size()-1).add(new MPoint(new Point(x,y), Direction.left));
				}
			}
		}

		for (LinkedList<MPoint> path : paths) {
			MPoint current = path.getFirst();
			while (current.nextDirection != Direction.end) {
				if (current.nextDirection == Direction.up) {
					Point p = current.p;
					Point nyPoint = new Point(p.x, p.y-1);
					path.add(new MPoint(nyPoint, getDirectionAt(nyPoint)));
					current = path.getLast();
				}
				else if (current.nextDirection == Direction.down) {
					Point p = current.p;
					Point nyPoint = new Point(p.x, p.y+1);
					path.add(new MPoint(nyPoint, getDirectionAt(nyPoint)));
					current = path.getLast();
				}
				else if (current.nextDirection == Direction.left) {
					Point p = current.p;
					Point nyPoint = new Point(p.x-1, p.y);
					path.add(new MPoint(nyPoint, getDirectionAt(nyPoint)));
					current = path.getLast();
				}
				else if (current.nextDirection == Direction.right) {
					Point p = current.p;
					Point nyPoint = new Point(p.x+1, p.y);
					path.add(new MPoint(nyPoint, getDirectionAt(nyPoint)));
					current = path.getLast();
				}
				else if (current.nextDirection == null) {
					System.out.println("null");
				}
				else {
					System.out.println("hmm?");
				}
			}
		}

		// Skriv ut alla paths:
		/*for (LinkedList<MPoint> path : paths) {
			for (MPoint p : path)
				System.out.println("asdf: " + p.p.x + " " + p.p.y);

		}*/
	}
	
	// Helper method for findNext
	// if intersection this returns the direction of the previous MPoint
	private Direction getDirectionAt(Point p) {
		char c = map[p.y][p.x];
		if (c == 'u')
			return Direction.up;
		else if (c == 'n')
			return Direction.down;
		else if (c == 'h')
			return Direction.right;
		else if (c == 'v')
			return Direction.left;
		else if (c == 'U')
			return Direction.up;
		else if (c == 'N')
			return Direction.down;
		else if (c == 'H')
			return Direction.right;
		else if (c == 'V')
			return Direction.left;
		else if (c == '3')
			return Direction.end;

		return null;
	}
	public LinkedList<LinkedList<MPoint>> getPaths() {
		return paths;
	}

	public LinkedList<MPoint> getPath(Point startPoint) {
		for (LinkedList<MPoint> path : paths) {
			if (path.getFirst().p.x == startPoint.x && path.getFirst().p.y == startPoint.y) {
				return path;
			}
		}

		System.out.println("Cant find a path starting at:" + startPoint.x + " " + startPoint.y);
		return null;
	}
	public Set<Point> getRoadPoints() {
		Set<Point> road = new HashSet<Point>();
		
		for (LinkedList<MPoint> path : paths) {
			for (MPoint p : path)
				road.add(p.p);
				
		}
		return road;
	}
	public List<Point> getStartPoints() {
		LinkedList<Point> startPoints = new LinkedList<Point>();
		for (LinkedList<MPoint> path : paths)
			startPoints.add(path.getFirst().p);
				
		return startPoints;
	}
	public void generateRoad() {
		Bitmap lr = ResourceAllocator.getDrawable(R.drawable.road, true);
		Bitmap ud = rotate(90, ResourceAllocator.getDrawable(R.drawable.road, true));
		Bitmap lu = ResourceAllocator.getDrawable(R.drawable.roadcurve, true);
		Bitmap ld = rotate(270, ResourceAllocator.getDrawable(R.drawable.roadcurve, true));
		Bitmap ur = rotate(90,ResourceAllocator.getDrawable(R.drawable.roadcurve, true));
		Bitmap rd = rotate(180, ResourceAllocator.getDrawable(R.drawable.road, true));
		
		Bitmap sr = ResourceAllocator.getDrawable(R.drawable.roaddeadend, true);
		Bitmap sl = rotate(180, ResourceAllocator.getDrawable(R.drawable.roaddeadend, true));
		Bitmap su = rotate(90, ResourceAllocator.getDrawable(R.drawable.roaddeadend, true));
		Bitmap sd = rotate(270, ResourceAllocator.getDrawable(R.drawable.roaddeadend, true));
		

		Point pFrom, pTo = null;
		for (LinkedList<MPoint> path : paths) {
			pFrom = null;
			System.out.println(path.size());
			
			for (MPoint p : path) {
				Point pNow = p.p;
				if (p.nextDirection == Direction.up)
					pTo = new Point(p.p.x, p.p.y-1);
				else if (p.nextDirection == Direction.down)
					pTo = new Point(p.p.x, p.p.y+1);
				else if (p.nextDirection == Direction.left)
					pTo = new Point(p.p.x-1, p.p.y);
				else if (p.nextDirection == Direction.right)
					pTo = new Point(p.p.x+1, p.p.y);
				else if (p.nextDirection == Direction.end) {
					System.out.println("slutet");
					pTo = null;
				}
				else { 
					System.out.println("sdf");
				}
				
				if (pFrom == null) {
					if (pTo == null) {
					}
					else {
						if (p.nextDirection == Direction.up)
							roadBitmaps.put(pNow, su);
						else if (p.nextDirection == Direction.down)
							roadBitmaps.put(pNow, sd);
						else if (p.nextDirection == Direction.left)
							roadBitmaps.put(pNow, sl);
						else if (p.nextDirection == Direction.right)
							roadBitmaps.put(pNow, sr);
						
					}
				}
				else if (pTo == null) {
					System.out.println("pto är null");
				}
				else {
					if (pNow == null)
						System.out.println("pnow är null");
					
					
					if ((pFrom.x-1) == pNow.x && pFrom.y == pNow.y) {
						if ((pNow.x+1) == pTo.x && pNow.y == pTo.y ) {
							roadBitmaps.put(pNow, lr);
						}
						else if (pNow.x == pTo.x && (pNow.y+1) == pTo.y ) {
							roadBitmaps.put(pNow, ld);
						}
						else if (pNow.x == pTo.x && (pNow.y-1) == pTo.y ) { 
							roadBitmaps.put(pNow, ld);
						}
						else if (pNow.x-1 == pTo.x &&  pNow.y == pTo.y ) {
							roadBitmaps.put(pNow, lr);
						}
						else {
							System.out.println("fel från vänster f:" + pFrom + " n:" + pNow + " t:" + pTo);
						}
					}
					else if ((pFrom.x+1) == pNow.x && pFrom.y == pNow.y) { 
						if ((pNow.x+1) == pTo.x && pNow.y == pTo.y ) {
							roadBitmaps.put(pNow, lr);
						}
						else if (pNow.x == pTo.x && (pNow.y+1) == pTo.y ) { 
							roadBitmaps.put(pNow, rd);
						}
						else if ((pNow.x) == pTo.x && (pNow.y-1) == pTo.y ) {
							roadBitmaps.put(pNow, ur);
						}
						else if ((pNow.x-1) == pTo.x && pNow.y == pTo.y ) {
							roadBitmaps.put(pNow, lu);
						}
						else {
							System.out.println("fel från höger");
						}
					}
					
					else if (pFrom.x == pNow.x && pFrom.y+1 == pNow.y) { 
						if ((pNow.x+1) == pTo.x && pNow.y == pTo.y ) { 
							roadBitmaps.put(pNow, rd);
						}
						else if (pNow.x == pTo.x && (pNow.y+1) == pTo.y ) { 
							roadBitmaps.put(pNow, ud);
						}
						else if ((pNow.x) == pTo.x && (pNow.y-1) == pTo.y ) { 
							roadBitmaps.put(pNow, ud);
						}
						else if ((pNow.x-1) == pTo.x && pNow.y == pTo.y ) { 
							roadBitmaps.put(pNow, rd);
						}
						else {
							System.out.println("fel nedifrån");
						}
					}
					else if (pFrom.x == pNow.x && (pFrom.y-1) == pNow.y) { 
						if ((pNow.x+1) == pTo.x && pNow.y == pTo.y ) { 
							roadBitmaps.put(pNow, ur);
						}
						else if (pNow.x == pTo.x && (pNow.y+1) == pTo.y ) { 
							roadBitmaps.put(pNow, ud);
						}
						else if ((pNow.x) == pTo.x && (pNow.y-1) == pTo.y ) { 
							roadBitmaps.put(pNow, ud);
						}
						else if ((pNow.x-1) == pTo.x && pNow.y == pTo.y ) { 
							roadBitmaps.put(pNow, lu);
						}
						else {
							System.out.println("fel uppifrån");
						}
					}
					else {
						System.out.println("hitta inget:  pFrom: "+ pFrom + " pNow :" + pNow + " pTo:" + pTo);
					}
				}
				pFrom = pNow;
			}
		}
		
		System.out.println(roadBitmaps.size());
	}
	public Map<Point, Bitmap> getRoadBitmaps() {
		return roadBitmaps;
	}
	/**
	 * Rotates a bitmap
	 * @param degrees degrees to rotate the bitmap
	 * @param orgBitmap The bitmap to rotate
	 * @return returns the new rotated bitmap
	 */
	public static Bitmap rotate(int degrees, Bitmap orgBitmap) {
		Matrix matrix = new Matrix();
		matrix.postRotate(degrees);
		if (degrees == 90 || degrees == 270) {
			orgBitmap = Bitmap.createScaledBitmap(orgBitmap, orgBitmap.getHeight(), orgBitmap.getWidth(), false);
			Bitmap rotatedBitmap = Bitmap.createBitmap(orgBitmap, 0, 0, orgBitmap.getWidth(), orgBitmap.getHeight(), matrix, true);
			return rotatedBitmap;
		}
		else {
			Bitmap rotatedBitmap = Bitmap.createBitmap(orgBitmap, 0, 0, orgBitmap.getWidth(), orgBitmap.getHeight(), matrix, true);
			return rotatedBitmap;	
		}
	}
}
